
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'


class MyPromise {
    constructor(executor) {
        executor(this.resolve, this.reject);
    }

    status = PENDING // 状态
    value = undefined // 成功返回值
    reason = undefined // 失败原因
    successCallback = [];
    failCallback = [];

    resolve = value => {
        if (this.status !== PENDING) return
        this.value = value;
        this.status = FULFILLED

        while(this.successCallback.length > 0) {
            this.successCallback.shift()(this.value);
        }
    }
    reject = reason => {
        if (this.status !== PENDING) return
        this.reason = reason;
        this.status = REJECTED;

        while(this.failCallback.length > 0) {
            this.failCallback.shift()(this.reason);
        }
    }

    then(successCallback, failCallback) {
        successCallback = successCallback || (value => value)

        const promise2 = new MyPromise((resolve, reject) => {
            if (this.status === FULFILLED) {
                let x = successCallback(this.value);
                resolvePromise(x, resolve, reject);
                // successCallback(this.value);
            } else if (this.status === REJECTED) {
                failCallback(this.reason);
            } else {
                // 将成功回调和失败回调存储起来
                this.successCallback.push(successCallback);
                this.failCallback.push(failCallback);
            }
        })
        return promise2;
    }

    static all(array) {
        let result = [];
        return new Promise((resolve, reject) => {
            for (let i = 0; i < array.length; i++) {
                const current = array[i];
                if (current instanceof MyPromise) {
                    current.then(value => { result[i] = value  }, reason => reject(reason));
                } else {
                    result[i] = current;
                }
            }
            resolve(result);
        })
    }

    static resolve(value) {
        if (value instanceof MyPromise) return value;
        return new MyPromise(resolve => resolve(value));
    }
}

function resolvePromise(x, resolve, reject) {
    if (x instanceof MyPromise) {
        x.then(value => resolve(value), reason => reject(reason));
    } else {
        resolve(x);
    }
}

let promise = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        // resolve('success...')
        // reject('error...')
    }, 1000);
    resolve('success');
    // reject('error')
})
function p1 () {
    return new MyPromise((resolve, reject) => {
        resolve('p1')
    })
}
function p2 () {
    return new MyPromise((resolve, reject) => {
        resolve('p3')
    })
}
MyPromise.all(['1', p1(), p2(), '2'])
    .then(
        value => console.log(value),
        reason => console.log(reason)
    )


// promise.then(
//     value => {
//         console.log(value)
//         return 100
//     },
//     reason => console.log(reason)
// )
// .then(
//     value => console.log(value),
//     reason => console.log(reason)
// )